package com.ttxs.generator.output.js;

import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.util.FileUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.ttxs.generator.engine.CustomFreemarker;
import com.ttxs.generator.output.Output;
import com.ttxs.generator.util.PathUtils;
import com.ttxs.generator.util.TableInfoUtils;
import com.ttxs.generator.vo.TreeNode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

import static com.ttxs.generator.util.Constants.LINE_SEPARATOR;

@Slf4j
public class MenuData implements Output {
    public static final String FIRST_ROW = "const menuData = [" + LINE_SEPARATOR;
    public static final String LAST_ROW = "]" + LINE_SEPARATOR + "export default menuData";
    /**
     * 输出静态菜单的数据文件，输出路径为：src/data/menu/index.js
     *
     * @param templateEngine
     */
    @Override
    public void write(CustomFreemarker templateEngine) throws IOException {
        String artifactId = templateEngine.formBean().getArtifactId();
        String index = templateEngine.formBean().getPort();
        String menuJsPath = PathUtils.get(PathUtils.Vue.menu, templateEngine.formBean().getVueProjectPath());
        File menuJsFile = new File(menuJsPath + File.separator + "index.js");
        FileUtils.forceMkdirParent(menuJsFile);
        List<TreeNode> menus = createMenuTree(Long.valueOf(index), artifactId, templateEngine.getConfigBuilder().getTableInfoList());
        write(menuJsFile, menus);
    }

    private void write(File menuJsFile, List<TreeNode> menus) {
        try (RandomAccessFile randomAccessFile = new RandomAccessFile(menuJsFile, "rw")) {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
            String content = trimSquareBrackets(objectMapper.writeValueAsString(menus));
            long length = randomAccessFile.length();
            if(length == 0) {
                randomAccessFile.writeBytes(FIRST_ROW);
                randomAccessFile.write((content + LINE_SEPARATOR).getBytes());
                randomAccessFile.writeBytes(LAST_ROW);
            } else {
                // 定位至倒数第2行
                randomAccessFile.seek(length - LAST_ROW.getBytes().length);
                randomAccessFile.writeBytes(",");
                randomAccessFile.write((content + LINE_SEPARATOR).getBytes());
                randomAccessFile.writeBytes(LAST_ROW);
            }
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }

    private String trimSquareBrackets(String json) {
        StringBuilder builder = new StringBuilder(json);
        builder.deleteCharAt(builder.indexOf("["));
        builder.deleteCharAt(builder.lastIndexOf("]"));
        return builder.toString();
    }

    /*private void write2(File menuJsFile, List<TreeNode> menus) {
        try (BufferedWriter out = new BufferedWriter(new FileWriter(menuJsFile))) {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
            out.write("const menuData = " + LINE_SEPARATOR);
            out.write(objectMapper.writeValueAsString(menus) + LINE_SEPARATOR);
            out.write("export default menuData");
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }*/

    private List<TreeNode> createMenuTree(long index, String artifactId, List<TableInfo> tableInfoList) {
        List<TreeNode> tree = new ArrayList<>();
        TreeNode root = new TreeNode().setId(index).setPid(0L).setTitle(artifactId);
        for (TableInfo tableInfo : tableInfoList) {
            if (tableInfo.isHavePrimaryKey() && !TableInfoUtils.isCompositeKey(tableInfo)) {
                String entityName = StringUtils.uncapitalize(tableInfo.getEntityName());
                TreeNode childrenItem = new TreeNode().setId(++index)
                        .setPid(root.getId())
                        .setApiUrl("/" + artifactId + "/" + entityName)
                        .setTitle(getTitle(tableInfo, entityName));
                root.getChildren().add(childrenItem);
            }
        }
        tree.add(root);
        return tree;
    }

    private String getTitle(TableInfo tableInfo, String entityName) {
        String title = entityName;
        if (StringUtils.hasText(tableInfo.getComment())) {
            String comment = tableInfo.getComment().trim();
            if(comment.endsWith("表")) {
                title = comment.substring(0, comment.lastIndexOf("表"));
            } else {
                title = comment;
            }
        }
        return title + "管理";
    }

}
